#ifndef __STUDENT_CPP__
#define __STUDENT_CPP__
#include "../include/student.h"
#include "../include/printer.h"


class Student;

void Student::print() {
    std::wstring gen;
    if (gender == 1) gen = L"男";
    else if (gender == 0) gen = L"女";
    else gen = L"其他";
    // wprintf(L"学号: %.8d  年龄: %3d  性别: %ls  姓名: %-16ls\n",
    //     sno, age, gen.c_str(), sname);
    Printer::fmtln(L"学号: {:0>8d}  年龄: {: >3d}  性别: {}  姓名: {}",
        sno, age, gen, sname);
}
bool Student::scan() {
    std::wstring wstr;
    wprintf(L"(姓名)     ");
    std::getline(std::wcin, wstr);
    if (wstr.empty()) {
        return false;
    }
    // 输入超长的部分会被丢弃, 并添加'\0'
    wcsncpy(sname, wstr.c_str(), sizeof(sname) / sizeof(*sname) - 1);
    wprintf(L"(年龄)     ");
    std::getline(std::wcin, wstr);
    age = stoi(wstr);
    wprintf(L"(性别 M/F) ");
    std::getline(std::wcin, wstr);
    gender = 0;
    if (wstr[0] < 128) {
        gender = wstr[0] & 1 ? 1 : 0;
    } else if (wstr == L"男") {
        gender = 1;
    } else if (wstr == L"女") {
    } else {
        gender = -1;
    }
    return true;
}

void Student::rescan() {
    this->print();
    std::wstring input;
    std::wcout << L"输入空行则保留原来的信息." << std::endl;
    std::wcout << L"(姓名)     ";
    std::getline(std::wcin, input);
    if (!input.empty()) {
        wcsncpy(sname, input.c_str(),
            sizeof(Student::sname) / sizeof(*Student::sname) - 1);
    }
    std::wcout << L"(年龄)     ";
    std::getline(std::wcin, input);
    if (!input.empty()) {
        age = stoi(input);
    }
    std::wcout << L"(性别 M/F) ";
    std::getline(std::wcin, input);
    if (!input.empty()) {
        gender = 0;
        if (input[0] < 128) {
            gender = input[0] & 1 ? 1 : 0;
        } else if (input == L"男") {
            gender = 1;
        } else if (input == L"女") {
        } else {
            gender = -1;
        }
    }
}

bool Student::found(
    std::vector<std::wstring>& strs,
    std::vector<int>& code) {

    bool can = true;
    std::partial_ordering res;

    // 将 wcscmp() 的比较结果包装为 wchar_t * 的 <=> 运算符. (C++20 的新东西)
    // 直接对 wchar_t * 使用 <=> 会比较指针大小, 这不是预期行为.
    // 试过直接对 std::wstring 运用 <=> , 报错了...
    auto scmp = [](const wchar_t * s1, const wchar_t * s2) {
        return wcscmp(s1, s2) <=> 0;
    };

    for (int i = 0; code[i] && can; i += 3) {
        // 这些魔法数字的说明请看 parse<Student>() 的注释.
        if (code[i] == 0x01) { res = scmp(sname, strs[code[i + 2]].c_str()); }
        if (code[i] == 0x02) { res = sno    <=> code[i + 2]; }
        if (code[i] == 0x03) { res = age    <=> code[i + 2]; }
        if (code[i] == 0x04) { res = gender <=> code[i + 2]; }

        switch (code[i + 1]) {
        case 0x11: if (res == 0) continue; goto NG;
        case 0x12: if (res != 0) continue; goto NG;
        case 0x13: if (res <  0) continue; goto NG;
        case 0x14: if (res <= 0) continue; goto NG;
        case 0x15: if (res >  0) continue; goto NG;
        case 0x16: if (res >= 0) continue; goto NG;
        }
        NG:
        can = false;
    }
    return can;
}


#endif /* __STUDENT_CPP__ */
